<?php

require '../database/tools/lib/CommonUtils.class.php';
require '../database/tools/lib/Db.class.php';
require './Probe.class.php';

switch (CommonUtils::input('action')) {
    case 'create_db':
        // 创建数据库
        (new ApiController())->createDb();
        break;
    case 'install_preview':
        // 预览安装
        (new ApiController())->installPreview();
        break;
    case 'install_db':
        // 安装数据库结构和体验数据
        (new ApiController())->installDb();
        break;
    case 'install_patch':
        // 安装补丁
        (new ApiController())->isntallPatch();
        break;
    case 'test_connection':
        // 测试数据库连接状态
        (new ApiController())->testConnection();
        break;
    case 'check_db':
        // 检测数据库是否存在
        (new ApiController())->checkDb();
        break;
    case 'serverinfo': // 获取服务器探针信息
        (new ApiController())->serverInfo();
        break;
    default: // 无效请求
        CommonUtils::responseJsonMessage(false, '无效的请求');
        break;
}

/**
 * 控制器
 */
class ApiController
{
    /**
     * 获取服务器探针信息
     */
    public function serverInfo()
    {
        $data = (new Probe())->getProbeData();
        CommonUtils::responseJsonMessage(true, 'ok', $data);
    }

    /**
     * 检测数据库是否存在
     */
    public function checkDb()
    {
        $postData = CommonUtils::input();
        $msgInfo = CommonUtils::validate([
            'host|服务器' => 'notblank',
            'port|端口' => 'notblank',
            'database|数据库' => 'notblank',
            'user|用户名' => 'notblank',
            'password|密码' => 'notblank',
        ], $postData);
        if (!$msgInfo['status']) {
            CommonUtils::outputJson($msgInfo);
        }
        $database = $postData['database'];
        unset($postData['database']);
        try {
            $pdo = new Db($postData);
            $pdo->connect();
            $pdo->execute("use {$database};");
        } catch (\PDOException $ex) {
            if (strpos($ex->getMessage(), 'Unknown database')) {
                CommonUtils::responseJsonMessage(true, '数据库不存在', 0);
            }
            CommonUtils::responseJsonMessage(false, $ex->getMessage());
        }
        CommonUtils::responseJsonMessage(true, '数据库已存在', 1);
    }

    /**
     * 测试数据库连接状态
     */
    public function testConnection()
    {
        $postData = CommonUtils::input();
        $msgInfo = CommonUtils::validate([
            'host|服务器' => 'notblank',
            'port|端口' => 'notblank',
            'database|数据库' => 'notblank',
            'user|用户名' => 'notblank',
            'password|密码' => 'notblank',
        ], $postData);
        if (!$msgInfo['status']) {
            CommonUtils::outputJson($msgInfo);
        }
        try {
            $pdo = new Db($postData);
            $pdo->connect();
        } catch (\PDOException $ex) {
            CommonUtils::responseJsonMessage(false, $ex->getMessage());
        }
        CommonUtils::responseJsonMessage(true, '连接成功');
    }

    /**
     * 创建数据库
     */
    public function createDb()
    {
        $postData = CommonUtils::input();
        $msgInfo = CommonUtils::validate([
            'host|服务器' => 'notblank',
            'port|端口' => 'notblank',
            'database|数据库' => 'notblank',
            'user|用户名' => 'notblank',
            'password|密码' => 'notblank',
        ], $postData);
        if (!$msgInfo['status']) {
            CommonUtils::outputJson($msgInfo);
        }
        $database = $postData['database'];
        unset($postData['database']);
        $n = 0;
        try {
            $pdo = new Db($postData);
            $pdo->connect();
            $n = $pdo->execute("CREATE DATABASE IF NOT EXISTS {$database} DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;");
        } catch (\PDOException $ex) {
            CommonUtils::responseJsonMessage(false, $ex->getMessage());
        }
        CommonUtils::responseJsonMessage(true, '数据库创建成功', $n);
    }

    /**
     * 安装预览
     */
    public function installPreview()
    {
        $schemaFile = '../database/src/database.sql';
        if (!file_exists($schemaFile)) {
            CommonUtils::responseJsonMessage(false, '数据库结构文件不存在');
        }
        $dataSrc = '../database/src/';
        if (!is_dir($dataSrc)) {
            CommonUtils::responseJsonMessage(false, '体验数据源文件目录不存在');
        }
        $runtimeDir = '../runtime/';
        if (!is_dir($runtimeDir)) {
            @mkdir($runtimeDir, 0777, true);
        }
        // 安装数据库结构
        $sqlSchemaArr = Db::parseSqlStatement(file($schemaFile), ';;', true);
        file_put_contents($runtimeDir . 'schema.sql', implode(PHP_EOL, $sqlSchemaArr));

        // 安装体验数据
        $sqlDataArr = Db::php2sql($dataSrc);
        file_put_contents($runtimeDir . 'data.sql', implode(PHP_EOL, $sqlDataArr));

        // 全部缓存
        $sqlAllArr = array_filter(array_merge($sqlSchemaArr, $sqlDataArr));
        file_put_contents($runtimeDir . 'install.sql', implode(PHP_EOL, $sqlAllArr));
        unset($sqlSchemaArr);
        unset($sqlDataArr);

        $sqlAllArrLite = [];
        foreach ($sqlAllArr as $stmt) {
            $sqlAllArrLite[] = ['text' => substr($stmt, 0, 60) . '...', 'status' => 0, 'error' => ''];
        }
        unset($sqlAllArr);
        CommonUtils::responseJsonMessage(true, '', $sqlAllArrLite);
    }

    /**
     * 分步安装数据库结构和体验数据
     */
    public function installDb()
    {
        $postData = CommonUtils::input();
        $msgInfo = CommonUtils::validate([
            'host|服务器' => 'notblank',
            'port|端口' => 'notblank',
            'database|数据库' => 'notblank',
            'user|用户名' => 'notblank',
            'password|密码' => 'notblank',
        ], $postData);
        if (!$msgInfo['status']) {
            CommonUtils::outputJson($msgInfo);
        }

        $step = intval($postData['step']);
        $sqlFile = '../runtime/install.sql';
        if (!file_exists($sqlFile)) {
            CommonUtils::responseJsonMessage(false, '数据库结构文件不存在');
        }
        $sqlAllArrLite = file($sqlFile);
        $stmt = $sqlAllArrLite[$step];
        try {
            $pdo = new Db($postData);
            $pdo->connect();
            $pdo->execute($stmt);
        } catch (\PDOException $ex) {
            CommonUtils::responseJsonMessage(false, $ex->getMessage(), ['step' => $step, 'sql' => $stmt]);
        }
        CommonUtils::responseJsonMessage(true, '执行成功', ['step' => $step, 'sql' => '']);
    }

    /**
     * 安装补丁
     */
    public function isntallPatch()
    {
        $postData = CommonUtils::input();
        $msgInfo = CommonUtils::validate([
            'host|服务器' => 'notblank',
            'port|端口' => 'notblank',
            'database|数据库' => 'notblank',
            'user|用户名' => 'notblank',
            'password|密码' => 'notblank',
            'admin_account|管理员账号' => 'notblank',
            'admin_password|管理员密码' => 'notblank',
        ], $postData);
        if (!$msgInfo['status']) {
            CommonUtils::outputJson($msgInfo);
        }

        $adminAccount = trim($postData['admin_account']);
        $adminPassword = trim($postData['admin_password']);
        $adminPassword = substr(md5($adminPassword . '1A7S5jQt'), 8, 16);
        $stmt = "update sw_auth_admins set user_name = '{$adminAccount}', password = '{$adminPassword}' where user_name = 'admin';";
        try {
            $pdo = new Db($postData);
            $pdo->connect();
            $pdo->execute($stmt);
        } catch (\PDOException $ex) {
            CommonUtils::responseJsonMessage(false, $ex->getMessage(), ['sql' => $stmt]);
        }
        CommonUtils::responseJsonMessage(true, '执行成功', ['sql' => '']);
    }
}
